//如果代理函数的时候，打印了函数的所有内容了，证明没有保护该函数
ffglobal = {};

//描述符检测，函数toString检测
!(() => {
    "use strict";
    const $toString = Function.toString;  //hook Function.toString 且命名为myToString
    //变量名取随机数防检测
    const myFunction_toString_symbol = Symbol('('.concat('', ')_', (Math.random() + '').toString(36)));
    const myToString = function () {
        return typeof this == 'function' && this[myFunction_toString_symbol] || $toString.call(this);   //谁调用这个方法,this就是谁,比如boda调用,这个this就是boda
    };

    function set_native(func, key, value) {
        //定义描述符
        Object.defineProperty(func, key, {
            "enumerable": false,
            "configurable": true,
            "writable": true,
            "value": value
        })
    };
    delete Function.prototype['toString']; //删除原型链上的toString
    set_native(Function.prototype, "toString", myToString); //自己定义个getter方法
    //myToString的 myFunction_toString_symbol属性设置为  function toString() { [native code] }
    //myFunction_toString_symbol= function toString() { [native code] }
    set_native(Function.prototype.toString, myFunction_toString_symbol, "function toString() { [native code] }"); //套个娃 保护一下我们定义的toString 否则就暴露了
    ffglobal.safefunction = (func, name) => {
        set_native(func, myFunction_toString_symbol, `function ${myFunction_toString_symbol, name || ''}() { [native code] }`);
        set_native(func, 'name', `${myFunction_toString_symbol, name || ''}`);
        // }
    }; //导出函数到globalThis
}).call(this);
//对象标识符检测
ffglobal.reNameObj = function reNameObj(obj, obname) {
    Object.defineProperty(obj.prototype, Symbol.toStringTag, {
        value: obname,
        configurable: true,
        writable: false,
        enumerable: false
    })
};

/////============================
window = globalThis;
delete global;
delete Buffer;
// delete process;
delete __dirname;
delete __filename;

const FF_DEBUG_LOG = false; // 控制开关，false 就不打印
globalThis.dconsole = {
    log: function (...args) {
        if (FF_DEBUG_LOG)
            console.log(...args);
    }
};
Object.assign(window, {
    outerHeight: 901,
    outerWidth: 1412,
    chrome: {},
    setTimeout: function () {
    },
    setInterval: function () {
    },
})
_crypto = {};
window.crypto = _crypto;
document = {};
_body = {};
_body.childElementCount = 29
_head = {};
_head.childElementCount = 41;
_2d = {};
_2d.fillRect = function (arg) {
    dconsole.log('2d中的fillRect的参数为==>', arg);
};
ffglobal.safefunction(_2d.fillRect, 'fillRect');
_2d.arc = function (arg) {
    dconsole.log('2d中的arc的参数为==>', arg);
    return 50;
};
ffglobal.safefunction(_2d.arc, 'arc');
_2d.stroke = function (arg) {
    dconsole.log('2d中的stroke的参数为==>', arg);
};
ffglobal.safefunction(_2d.stroke, 'stroke');
_2d.fillText = function (arg) {
    dconsole.log('2d中的fillText的参数为==>', arg);
};
ffglobal.safefunction(_2d.fillText, 'fillText');
_canvas = {};
_canvas.getContext = function (arg) {
    dconsole.log('canvas中的getContext的参数为==>', arg);
    if (arg == '2d') {
        return _2d;
    }
};
ffglobal.safefunction(_canvas.getContext, 'getContext');
_canvas.toDataURL = function (arg) {
    dconsole.log('canvas中的toDataURL的参数为==>', arg);
    return "";
};
ffglobal.safefunction(_canvas.toDataURL, 'toDataURL');
document.cookie = 'o2State={%22webp%22:true%2C%22avif%22:true}; __jdu=1751545604909534518369; pinId=briEibRb-h1YgxkG81uaz7V9-x-f3wj7; pin=jd_7eac037a858fc; unick=jd_8js7q5tn2s7n2h; _tp=aO5XtogPiplRTZPyN6P5Vkd5JC%2FQJe7kEmh0g0oTaNI%3D; shshshfpa=ab96e4b0-82d6-a907-9206-6c096fe807bb-1751545628; shshshfpx=ab96e4b0-82d6-a907-9206-6c096fe807bb-1751545628; mt_xid=V2_52007VwMUVl1cV14YSBxUBG8HEFdZWFtYGEEpXVBjCkcCCAhOWBsdGUAAZQAUTg1eVFMDHhoLDDdQEQBeXFBdL0oYXwF7AhROXVhDWhlCHFQOZwMiUG1YYlMfSB1eBmMEFFJcX1ZZGk4RWQ1XAxFRXw%3D%3D; areaId=19; ipLoc-djd=19-1607-4773-62123; TrackID=1oewTDv6eVflY_HJgkzuOTgmL_p-6JTPedCSo2I6Yy9OP7jfY6j_peKkFgRgw_yDoqoH1X4N6DllRX6TMyXVIr08DQYKqcjsiluMfFrdiN_uVhlZAsFX03PfWDdQl1ekr; 3AB9D23F7A4B3C9B=GNWKXUTIE6HBK6NALGSXSPDIJB4FOSTK2HH5HNAWZAUUMF5JYQCGOIB4252C7TECGDOSXSGLUC74Z5SQVPIKNU2LBE; __jda=76161171.1751545604909534518369.1751545604.1752832750.1753068550.13; __jdc=76161171; __jdv=76161171|direct|-|none|-|1753068549992; PCSYCityID=CN_440000_440300_0; UseCorpPin=jd_7eac037a858fc; 3AB9D23F7A4B3CSS=jdd03GNWKXUTIE6HBK6NALGSXSPDIJB4FOSTK2HH5HNAWZAUUMF5JYQCGOIB4252C7TECGDOSXSGLUC74Z5SQVPIKNU2LBEAAAAMYFMK6VIIAAAAAC7DFGFTMGATUJ4X; mail_times=2%2C2; sdtoken=AAbEsBpEIOVjqTAKCQtvQu17W40wBwWdzIcSHNPr9NfRKXz-0XOL1ZcnZfZGYSQPo0Gpu8E78NBQ92nwAEZV9r3vxF-OZtsog7f32rnjJ_Kh3mFBmAEV_lHvBZCKDkQA2Q; shshshfpb=BApXSypISKP1AYEqgcJFHsyDPBX7ULrZhBhMVUQdu9xJ1MppMe462; __jdb=76161171.6.1751545604909534518369|13.1753068550';
document.body = _body;
document.head = _head;
document.all = {
    [Symbol.toStringTag]: "HTMLCollection",
}
_documentElement = {}
document.documentElement = _documentElement
location = {
    "ancestorOrigins": {},
    "href": "https://www.jd.com/",
    "origin": "https://www.jd.com",
    "protocol": "https:",
    "host": "www.jd.com",
    "hostname": "www.jd.com",
    "port": "",
    "pathname": "/",
    "search": "",
    "hash": ""
};
navigator = {
    appCodeName: "Mozilla",
    appName: "Netscape",
    appVersion: "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
    cookieEnabled: true,
    doNotTrack: null,
    hardwareConcurrency: 12,
    language: "zh-CN",
    languages: ["zh-CN", "zh"],
    maxTouchPoints: 0,
    onLine: true,
    pdfViewerEnabled: true,
    platform: "Win32",
    plugins: {
        length: 4,
        [Symbol.toStringTag]: 'PluginArray',
        0: {
            name: 'PDF Viewer',
            [Symbol.toStringTag]: 'Plugin',
            length: 2
        },
        1: {
            name: 'ff_ss',
            [Symbol.toStringTag]: 'Plugin',
            length: 2
        },
        2: {
            name: 'ss_ff',
            [Symbol.toStringTag]: 'Plugin',
            length: 2
        },
        3: {
            name: 'FFloveSS',
            [Symbol.toStringTag]: 'Plugin',
            length: 2
        },
    },
    product: "Gecko",
    productSub: "20030107",
    userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
    vendor: "Google Inc.",
    vendorSub: "",
    webdriver: false,
};
history = {};
screen = {
    availHeight: 901,
    availLeft: 0,
    availTop: 0,
    availWidth: 1412,
    colorDepth: 24,
    height: 942,
    pixelDepth: 24,
    width: 1412,
};
localStorage = {};

sessionStorage = {};
_script = {};
_script.src = ""

/////============================
//里面全是函数
/////=========函数集合地===================
//window==========================================================================================================

window.addEventListener = function addEventListener(arg) {
    // if (arg === 'load') {
    //     return {}
    // }
    dconsole.log('window中的addEventListener的参数为==>', arg);
    debugger;
};
ffglobal.safefunction(window.addEventListener, 'addEventListener');

//document==========================================================================================================
document.querySelector = function querySelector(arg) {
    dconsole.log('document中的querySelector的参数为==>', arg);
};
ffglobal.safefunction(document.querySelector, 'querySelector');
document.createEvent = function createEvent(arg) {
    dconsole.log('document中的createEvent的参数为==>', arg);
    debugger;
};
ffglobal.safefunction(document.createEvent, 'createEvent');

document.createElement = function createElement(arg) {
    if (arg === "canvas") {
        return _canvas
    }
    if (arg === "script") {
        return _script
    }
    dconsole.log('document中的createElement的参数为==>', arg);
    debugger;
};
ffglobal.safefunction(document.createElement, 'createElement');
_getElementsByTagName_head = {
    0: {
        appendChild: function appendChild(arg) {
            dconsole.log('_getElementsByTagName_head中的appendChild的参数为==>', arg);
            debugger;
        }
    }
}
document.getElementsByTagName = function getElementsByTagName(arg) {
    if (arg == "head") {
        return _getElementsByTagName_head
    }
    // if (arg === 'meta') {
    //     return [
    //         {}, {
    //             content: content,
    //             parentNode: {
    //                 removeChild: function () { }
    //             },
    //             getAttribute: function () { }

    //         }
    //     ]
    // }
    // if (arg === 'script') {
    //     return {
    //         0: {
    //             getAttribute: function (res) {
    //                 if (res == 'r') {
    //                     return 'm'
    //                 }
    //             },
    //             parentElement: {
    //                 removeChild: function (res) { }
    //             }
    //         },
    //         1: {
    //             getAttribute: function (res) {
    //                 if (res == 'r') { return 'm' }
    //             },
    //             parentElement: {
    //                 removeChild: function (res) { }
    //             }
    //         },
    //         length: 2
    //     }
    // }
    // if (arg === "base") {
    //     return {
    //         length: 0
    //     }
    // }
    dconsole.log('document中的getElementsByTagName的参数为==>', arg);
    debugger;
};
ffglobal.safefunction(document.getElementsByTagName, 'getElementsByTagName');
document.addEventListener = function addEventListener(arg) {
    dconsole.log('document中的addEventListener的参数为==>', arg);
    debugger;
};
ffglobal.safefunction(document.addEventListener, 'addEventListener')
document.removeChild = function (arg) {
    dconsole.log('document中的removeChild的参数为==>', arg);
    debugger;
};
ffglobal.safefunction(document.removeChild, 'removeChild')
document.getElementById = function (arg) {
    dconsole.log('document中的getElementById的参数为==>', arg);
    debugger;
};
ffglobal.safefunction(document.getElementById, 'getElementById')

//localStorage==========================================================================================================

localStorage.getItem = function getItem(arg) {
    dconsole.log('localStorage中的getItem的参数为==>', arg);
    debugger;
};
ffglobal.safefunction(localStorage.getItem, 'getItem');
localStorage.setItem = function setItem(key, val) {
    dconsole.log('localStorage中的setItem的参数为==>', key, val);
    debugger;
};
ffglobal.safefunction(localStorage.setItem, 'setItem');
//==========================================================================================================

//===========代理===============
let count = 0;
let skipCount = 0; // 设置你想跳过的打印次数
// 你可以定义一个数组，用来存放你想要忽略的属性名
let ignoreList = ["window", "document", "navigator", "location", "localStorage", "sessionStorage"];

// let ignoreList = [];
function proxy(obj, objName) {
    let printedProps = new Set();  // 用 Set 来保存已经打印过的属性名,过滤掉重复属性
    let handler = {
        get(target, prop, receiver) {
            // 你可以检查 prop 是否在忽略列表中，如果是，就直接返回原始值，不进行拦截
            if (ignoreList.includes(prop)) {
                return Reflect.get(target, prop, receiver);
            }
            if (prop === 'all') {
                debugger;
            }
            // 其他部分不变
            if (!printedProps.has(prop)) {
                let result = Reflect.get(target, prop, receiver);
                count++;
                if (typeof result === 'function') {
                    if (result.toString().length <= 60) {
                        // 检查是否跳过打印
                        if (skipCount > 0) {
                            skipCount--;
                        } else {
                            dconsole.log('计数:', count, '[' + objName + ']', '获取属性', prop, '   [FF函数经过]=>', result.toString());
                        }
                    } else {
                        // 检查是否跳过打印
                        if (skipCount > 0) {
                            skipCount--;
                        } else {
                            dconsole.log('计数:', count, '[' + objName + ']', '获取属性(===toString值太长===):', prop);
                        }
                    }
                    result = proxy(result, objName + '.' + prop);  // 对函数属性进行递归代理
                } else if (typeof result === "object" && result !== null && result !== undefined) {
                    if (result.toString().length <= 60) {
                        // 检查是否跳过打印
                        if (skipCount > 0) {
                            skipCount--;
                        } else {
                            dconsole.log('计数:', count, '[' + objName + ']', '获取属性', prop, '   [OO对象经过]=>', result.toString());
                        }
                    } else {
                        // 检查是否跳过打印
                        if (skipCount > 0) {
                            skipCount--;
                        } else {
                            dconsole.log('计数:', count, '[' + objName + ']', '获取属性(===toString值太长===):', prop);
                        }
                    }
                    result = proxy(result, objName + '.' + prop);  // 对对象属性进行递归代理
                } else {
                    // 检查是否跳过打印
                    if (skipCount > 0) {
                        skipCount--;
                    } else {
                        dconsole.log('计数:', count, '[' + objName + ']', '获取属性', prop, '   [值为]=>', result);
                    }
                }
                printedProps.add(prop);  // 记录已经打印过的属性
                return result
            }
            return Reflect.get(target, prop, receiver);
        },
        set(target, propKey, value, receiver) {
            // 同样，你可以检查 propKey 是否在忽略列表中，如果是，就直接返回原始值，不进行拦截
            if (ignoreList.includes(propKey)) {
                return Reflect.set(target, propKey, value, receiver);
            }
            // 其他部分不变
            if (!printedProps.has(propKey)) {
                count++;
                if (typeof value === 'function') {
                    if (value.toString().length <= 60) {
                        // 检查是否跳过打印
                        if (skipCount > 0) {
                            skipCount--;
                        } else {
                            dconsole.log('计数:', count, '[' + objName + ']', "  设置属性:", propKey, "   value:   ", value.toString())
                        }
                    } else {
                        // 检查是否跳过打印
                        if (skipCount > 0) {
                            skipCount--;
                        } else {
                            dconsole.log('计数:', count, '[' + objName + ']', "  设置属性(===toString值太长===):", propKey)
                        }
                    }
                } else {
                    // 检查是否跳过打印
                    if (skipCount > 0) {
                        skipCount--;
                    } else {
                        dconsole.log('计数:', count, '[' + objName + ']', "  设置属性:", propKey, "   value:   ", value);
                    }
                }
                printedProps.add(propKey);  // 记录已经打印过的属性
            }
            return Reflect.set(target, propKey, value, receiver);
        }
    };
    return new Proxy(obj, handler);
}

/////=========构造函数============
Window = function Window() {
};
ffglobal.reNameObj(Window, 'Window');
Document = function Document() {
};
ffglobal.reNameObj(Document, 'Document');
HTMLDocument = function HTMLDocument() {
};
ffglobal.reNameObj(HTMLDocument, 'HTMLDocument');
Location = function Location() {
};
ffglobal.reNameObj(Location, 'Location');
History = function History() {
};
ffglobal.reNameObj(History, 'History');
Navigator = function Navigator() {
};
ffglobal.reNameObj(Navigator, 'Navigator');
Screen = function Screen() {
};
ffglobal.reNameObj(Screen, 'Screen');
Storage = function Storage() {
};
ffglobal.reNameObj(Storage, 'Storage');
Node = function Node() {
};
ffglobal.reNameObj(Node, 'Node');
Element = function Element() {
};
ffglobal.reNameObj(Element, 'Element');
HTMLAllCollection = function HTMLAllCollection() {
};
ffglobal.reNameObj(HTMLAllCollection, 'HTMLAllCollection');
////================原型绑定================///////
window.__proto__ = Window.prototype;
document.__proto__ = HTMLDocument.prototype;
HTMLDocument.prototype.__proto__ = Document.prototype;
Element.prototype.__proto__ = Node.prototype;
location.__proto__ = Location.prototype;
history.__proto__ = History.prototype;
navigator.__proto__ = Navigator.prototype;
screen.__proto__ = Screen.prototype;
localStorage.__proto__ = Storage.prototype;
sessionStorage.__proto__ = Storage.prototype;
document.all.__proto__ = HTMLAllCollection.prototype;
/////===================代理对象=====================//////
window = proxy(window, 'window')
document = proxy(document, 'document')
navigator = proxy(navigator, 'navigator')
location = proxy(location, 'location')
history = proxy(history, 'history')
screen = proxy(screen, 'screen')
localStorage = proxy(localStorage, 'localStorage')
sessionStorage = proxy(sessionStorage, 'sessionStorage')
Element = proxy(Element, 'Element')
_body = proxy(_body, '_body')
_head = proxy(_head, '_head')
_canvas = proxy(_canvas, '_canvas')
_2d = proxy(_2d, '_2d')
_documentElement = proxy(_documentElement, '_documentElement')
_crypto = proxy(_crypto, '_crypto')
_script = proxy(_script, '_script')
_getElementsByTagName_head = proxy(_getElementsByTagName_head, '_getElementsByTagName_head')
document.all = proxy(document.all, 'document.all')
